/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _DAL_FASTDDS_ENTITY_MAPPING_MANAGER_HPP_
#define _DAL_FASTDDS_ENTITY_MAPPING_MANAGER_HPP_

#include <thread>
#include <shared_mutex>
#include <unordered_map>
#include "dal/topic.h"
#include "dal/publisher.h"
#include "dal/subscriber.h"
#include "dal/domain_participant.h"
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>

using namespace eprosima::fastdds::dds;

static std::unordered_map<DataReader*, dal_datareader_t*> datareaderMap;
static std::unordered_map<DataWriter*, dal_datawriter_t*> datawriterMap;
static std::unordered_map<Publisher*, dal_publisher_t*> publisherMap;
static std::unordered_map<Subscriber*, dal_subscriber_t*> subscriberMap;
static std::unordered_map<Topic*, dal_topic_t*> topicMap;
static std::unordered_map<DomainParticipant*, dal_domain_participant_t*> domainParticipantMap;

static std::shared_timed_mutex datareaderMtx;
static std::shared_timed_mutex datawriterMtx;
static std::shared_timed_mutex publisherMtx;
static std::shared_timed_mutex subscriberMtx;
static std::shared_timed_mutex topicMtx;
static std::shared_timed_mutex domainParticipantMtx;

void EntityMappingAddDataReader(DataReader* key, dal_datareader_t* value);
void EntityMappingRemoveDataReader(DataReader* key);
void EntityMappingUpdateDataReader(DataReader* key, dal_datareader_t* value);
dal_datareader_t* EntityMappingGetDataReader(DataReader* key);
dal_datareader_t* EntityMappingGetOrAddDataReader(DataReader* f_reader, dal_datareader_t* d_reader);

void EntityMappingAddDataWriter(DataWriter* key, dal_datawriter_t* value);
void EntityMappingRemoveDataWriter(DataWriter* key);
void EntityMappingUpdateDataWriter(DataWriter* key, dal_datawriter_t* value);
dal_datawriter_t* EntityMappingGetDataWriter(DataWriter* key);
dal_datawriter_t* EntityMappingGetOrAddDataWriter(DataWriter* f_writer, dal_datawriter_t* d_reader);

void EntityMappingAddPublisher(Publisher* key, dal_publisher_t* value);
void EntityMappingRemovePublisher(Publisher* key);
void EntityMappingUpdatePublisher(Publisher* key, dal_publisher_t* value);
dal_publisher_t* EntityMappingGetPublisher(Publisher* key);

void EntityMappingAddSubscriber(Subscriber* key, dal_subscriber_t* value);
void EntityMappingRemoveSubscriber(Subscriber* key);
void EntityMappingUpdateSubscriber(Subscriber* key, dal_subscriber_t* value);
dal_subscriber_t* EntityMappingGetSubscriber(Subscriber* key);

void EntityMappingAddTopic(Topic* key, dal_topic_t* value);
void EntityMappingRemoveTopic(Topic* key);
void EntityMappingUpdateTopic(Topic* key, dal_topic_t* value);
dal_topic_t* EntityMappingGetTopic(Topic* key);

void EntityMappingAddDomainParticipant(DomainParticipant* key, dal_domain_participant_t* value);
void EntityMappingRemoveDomainParticipant(DomainParticipant* key);
void EntityMappingUpdateDomainParticipant(DomainParticipant* key, dal_domain_participant_t* value);
dal_domain_participant_t* EntityMappingUpdateGetDomainParticipant(DomainParticipant* key);

#endif  // _DAL_FASTDDS_ENTITY_MAPPING_MANAGER_HPP_